package mongo;

import com.mongodb.*;
import com.mongodb.client.FindIterable;
import com.mongodb.client.MongoCollection;
import com.mongodb.client.MongoCursor;
import com.mongodb.client.MongoDatabase;
import net.sf.json.JSONObject;
import org.bson.Document;
import test.HospitalTopic;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Calendar;
import java.util.List;

/**
 * USER: lintc 【lintiancong@zhuojianchina.com】
 * DATE: 2017-02-05 15:39
 */
public class MongoTest {
    // 连接 mongodb 服务
    private static MongoClient mongoClient;
    static {
        MongoClientOptions.Builder build = new MongoClientOptions.Builder();
        //与目标数据库能够建立的最大connection数量,默认100
        build.connectionsPerHost(100);
        build.threadsAllowedToBlockForConnectionMultiplier(5);
        /*
         * 一个线程访问数据库的时候，在成功获取到一个可用数据库连接之前的最长等待时间为2分钟
         * 这里比较危险，如果超过maxWaitTime都没有获取到这个连接的话，该线程就会抛出Exception
         * 故这里设置的maxWaitTime应该足够大，以免由于排队线程过多造成的数据库访问失败
         */
        build.maxWaitTime(120000);
        //与数据库建立连接的timeout设置为1分钟
        build.connectTimeout(60000);
        build.socketTimeout(120000);

        MongoClientOptions myOptions = build.build();
        ServerAddress address = new ServerAddress("192.168.0.216", 27017);
        // 权限配置
        MongoCredential api_flow_credential = MongoCredential.createCredential(
                "zfh", "api_flow", "zfh666".toCharArray());
        MongoCredential api_warning_credential = MongoCredential.createCredential(
                "zfh", "api_warning", "zfh666".toCharArray());
        MongoCredential api_wash_credential = MongoCredential.createCredential(
                "zfh", "api_wash", "zfh666".toCharArray());
        MongoCredential test_credential = MongoCredential.createCredential(
                "zfh", "test", "zfh666".toCharArray());
        MongoCredential nginx_credential = MongoCredential.createCredential(
                "zfh", "nginx_flow", "zfh666".toCharArray());
        mongoClient = new MongoClient(address, Arrays.asList(api_flow_credential, api_warning_credential, api_wash_credential, test_credential, nginx_credential), myOptions);
    }
    // 连接 数据库 原始日志
    private static MongoDatabase apiFlow = mongoClient.getDatabase("api_flow");

    // 预警数据
    private static MongoDatabase apiWarning = mongoClient.getDatabase("api_warning");

    // 清洗数据
    private static MongoDatabase apiWash = mongoClient.getDatabase("api_wash");

    // 测试
    public static MongoDatabase test = mongoClient.getDatabase("test");

    // 测试
    public static MongoDatabase nginxFlow = mongoClient.getDatabase("nginx_flow");

    // 选择表
    private static MongoCollection<Document> collection = apiFlow.getCollection(HospitalTopic.APP_GDYXYFSYY);

    public static MongoCollection<Document> getCollection(String name) {
        return apiFlow.getCollection(name);
    }

    public static void main(String[] args) {
        List<JSONObject> list = getDocList();
        for (JSONObject object : list) {
            System.out.println(object);
        }
    }

    public static List<JSONObject> getDocList() {
        MongoCollection<Document> collection = getCollection("api_doc");
        FindIterable<Document> list = collection.find(new BasicDBObject());
        MongoCursor<Document> iterator = list.iterator();
        List<JSONObject> l = new ArrayList<>();
        while (iterator.hasNext()) {
            //            System.out.println(iterator.next());
            l.add(JSONObject.fromObject(iterator.next()));
        }
        return l;
    }

    /**
     * 遍历所有文档
     * @param collection
     */
    public static void getList(MongoCollection<Document> collection) {
        FindIterable<Document> findIterable = collection.find();
        MongoCursor<Document> mongoCursor = findIterable.iterator();
        while (mongoCursor.hasNext()) {
            System.out.println(mongoCursor.next().toJson());
        }
    }

    /**
     * 插入单条数据
     * @param collection
     */
    public static void insertOne(MongoCollection<Document> collection, JSONObject obj) {
        Document d = Document.parse(obj.toString());
        collection.insertOne(d);
    }

    /**
     * 插入多条数据
     * @param collection
     */
    public static void insertAllList(MongoCollection<Document> collection, List<JSONObject> objList) {
        List<Document> list = new ArrayList<Document>();
        if(objList.size() >= 500) {
            for (JSONObject obj : objList) {
                list.add(Document.parse(obj.toString()));
                if(list.size() == 500) {
                    collection.insertMany(list);
                    list = new ArrayList<Document>();
                }
            }
        } else {
            for (JSONObject obj : objList) {
                list.add(Document.parse(obj.toString()));
            }
        }
        if(list.size() > 0)
            collection.insertMany(list);
    }

    /**
     * 插入多条数据
     * @param collection
     */
    public static void insertList(MongoCollection<Document> collection, List<JSONObject> objList) {
        List<Document> list = new ArrayList<Document>();
        for (JSONObject obj : objList) {
            list.add(Document.parse(obj.toString()));
        }
        if(list.size() > 0)
            collection.insertMany(list);
    }

    /**
     * 查询
     * @param collection
     * @param obj
     * @return
     */
    public static MongoCursor<Document> find(MongoCollection<Document> collection, BasicDBObject obj) {
        return collection.find(obj).iterator();
    }

    /**
     * 分页查询
     * @param collection
     * @param obj
     * @param page 页码
     * @param pageSize 大小
     * @return
     */
    public static MongoCursor<Document> pageFind(MongoCollection<Document> collection, BasicDBObject obj,
                                                 int page, int pageSize) {
        return collection.find(obj).skip((page - 1 ) * 10).sort(new BasicDBObject()).limit(pageSize).iterator();
    }

    /**
     * 插入多条数据
     * @param collection
     */
    public static void insertStrList(MongoCollection<Document> collection, List<String> strList) {
        List<Document> list = new ArrayList<>();
        if(strList.size() >= 300) {
            for (String obj : strList) {
                list.add(Document.parse(obj));
                if(list.size() == 300) {
                    long start = System.currentTimeMillis();
                    System.out.println("开始添加 ：");
                    collection.insertMany(list);
                    list = new ArrayList<>();
                    System.out.println("添加 ：" + (System.currentTimeMillis() - start));
                }
            }
        } else {
            for (String obj : strList) {
                list.add(Document.parse(obj));
            }
        }
        if(list.size() > 0)
            collection.insertMany(list);
    }

    public static List<JSONObject> getCatchList(String topic, String index) {
        List<JSONObject> list = new ArrayList<>();
        JSONObject zy;
        Calendar c = Calendar.getInstance();
        c.setTime(DateUtil.getyyyy_MM_dd("2017-03-01"));
        for (int i = 0; i < 23; i++) {
            zy = new JSONObject();
            zy.put("topic", topic);
            zy.put("index", index);
            zy.put("date", DateUtil.dateToString(c.getTime(), "yyyy.MM.dd"));
            zy.put("catch_num", 0);
            zy.put("state", "true");
            c.add(Calendar.DAY_OF_YEAR, 1);
            list.add(zy);
        }
        return list;
    }
}
